import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;

public class PolygonGUI extends JFrame {
    private final List<Shape> shapes = new ArrayList<>();
    private Shape currentShape;
    private JTextField parameter1Field;
    private JTextField parameter2Field;
    private JTextField parameter3Field;
    private JComboBox<String> shapeComboBox;
    private DrawingPanel drawingPanel;
    private JTextArea infoTextArea;
    private JLabel param1Label;
    private JLabel param2Label;
    private JLabel param3Label;

    public PolygonGUI() {
        initializeUI();
    }

    private void initializeUI() {
        setTitle("多边形绘制工具 - 图形计算器");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new BorderLayout(10, 10));

        // 创建输入面板
        JPanel inputPanel = createInputPanel();
        add(inputPanel, BorderLayout.NORTH);

        // 创建绘图和信息面板
        JSplitPane centerSplitPane = createCenterPanel();
        add(centerSplitPane, BorderLayout.CENTER);

        // 创建按钮面板
        JPanel buttonPanel = createButtonPanel();
        add(buttonPanel, BorderLayout.SOUTH);

        pack();
        setSize(900, 600);
        setLocationRelativeTo(null);
    }

    private JPanel createInputPanel() {
        JPanel panel = new JPanel(new FlowLayout());
        panel.setBorder(BorderFactory.createTitledBorder("图形参数输入"));

        // 图形类型选择
        panel.add(new JLabel("图形类型:"));
        String[] shapes = {"长方形", "圆形", "三角形", "平行四边形", "梯形", "菱形",
                "正多边形", "椭圆", "扇形", "圆环", "10边星形"};
        shapeComboBox = new JComboBox<>(shapes);
        panel.add(shapeComboBox);

        // 参数1输入
        param1Label = new JLabel("参数1:");
        panel.add(param1Label);
        parameter1Field = new JTextField(6);
        panel.add(parameter1Field);

        // 参数2输入
        param2Label = new JLabel("参数2:");
        panel.add(param2Label);
        parameter2Field = new JTextField(6);
        panel.add(parameter2Field);

        // 参数3输入
        param3Label = new JLabel("参数3:");
        panel.add(param3Label);
        parameter3Field = new JTextField(6);
        panel.add(parameter3Field);
        parameter3Field.setVisible(false);

        // 动态更新参数标签
        shapeComboBox.addActionListener(e -> updateParameterLabels());
        updateParameterLabels();

        return panel;
    }

    private JSplitPane createCenterPanel() {
        // 绘图面板
        drawingPanel = new DrawingPanel();

        // 信息显示区域
        infoTextArea = new JTextArea(12, 35);
        infoTextArea.setEditable(false);
        infoTextArea.setBorder(BorderFactory.createTitledBorder("图形信息"));
        infoTextArea.setFont(new Font("宋体", Font.PLAIN, 12));
        JScrollPane scrollPane = new JScrollPane(infoTextArea);

        JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, drawingPanel, scrollPane);
        splitPane.setResizeWeight(0.6);

        return splitPane;
    }

    private JPanel createButtonPanel() {
        JPanel panel = new JPanel(new FlowLayout());

        JButton calculateButton = new JButton("计算并绘制");
        calculateButton.addActionListener(new CalculateListener());

        JButton viewAllButton = new JButton("查看所有图形");
        viewAllButton.addActionListener(e -> showAllShapes());

        JButton statsButton = new JButton("统计信息");
        statsButton.addActionListener(e -> showStatistics());

        JButton clearButton = new JButton("清空图形");
        clearButton.addActionListener(e -> clearShapes());

        panel.add(calculateButton);
        panel.add(viewAllButton);
        panel.add(statsButton);
        panel.add(clearButton);

        return panel;
    }

    private void updateParameterLabels() {
        String selectedShape = (String) shapeComboBox.getSelectedItem();
        if (selectedShape == null) return;

        // 重置所有输入框状态
        parameter1Field.setEnabled(true);
        parameter2Field.setEnabled(true);
        parameter2Field.setVisible(true);
        parameter3Field.setVisible(false);

        // 清空输入框提示
        parameter1Field.setToolTipText(null);
        parameter2Field.setToolTipText(null);
        parameter3Field.setToolTipText(null);

        switch (selectedShape) {
            case "长方形":
                param1Label.setText("长度:");
                param2Label.setText("宽度:");
                parameter1Field.setToolTipText("请输入长方形的长度");
                parameter2Field.setToolTipText("请输入长方形的宽度");
                break;

            case "圆形":
                param1Label.setText("半径:");
                param2Label.setText("未使用:");
                parameter2Field.setEnabled(false);
                parameter1Field.setToolTipText("请输入圆的半径");
                break;

            case "三角形":
                param1Label.setText("底边:");
                param2Label.setText("高度:");
                parameter1Field.setToolTipText("请输入三角形的底边长度");
                parameter2Field.setToolTipText("请输入三角形的高度");
                break;

            case "正多边形":
                param1Label.setText("边长:");
                param2Label.setText("边数:");
                parameter1Field.setToolTipText("请输入正多边形的边长");
                parameter2Field.setToolTipText("请输入正多边形的边数（≥3）");
                break;

            case "椭圆":
                param1Label.setText("长轴:");
                param2Label.setText("短轴:");
                parameter1Field.setToolTipText("请输入椭圆的长轴长度");
                parameter2Field.setToolTipText("请输入椭圆的短轴长度");
                break;

            case "扇形":
                param1Label.setText("半径:");
                param2Label.setText("角度:");
                parameter1Field.setToolTipText("请输入扇形的半径");
                parameter2Field.setToolTipText("请输入扇形的角度（度数）");
                break;

            case "圆环":
                param1Label.setText("内半径:");
                param2Label.setText("外半径:");
                parameter1Field.setToolTipText("请输入圆环的内半径");
                parameter2Field.setToolTipText("请输入圆环的外半径（必须大于内半径）");
                break;

            case "菱形":
                param1Label.setText("对角线1:");
                param2Label.setText("对角线2:");
                parameter1Field.setToolTipText("请输入菱形的第一条对角线长度");
                parameter2Field.setToolTipText("请输入菱形的第二条对角线长度");
                break;

            case "平行四边形":
                param1Label.setText("底边:");
                param2Label.setText("高度:");
                parameter1Field.setToolTipText("请输入平行四边形的底边长度");
                parameter2Field.setToolTipText("请输入平行四边形的高度");
                break;

            case "梯形":
                param1Label.setText("上底:");
                param2Label.setText("下底:");
                param3Label.setText("高度:");
                parameter3Field.setVisible(true);
                parameter1Field.setToolTipText("请输入梯形的上底长度");
                parameter2Field.setToolTipText("请输入梯形的下底长度");
                parameter3Field.setToolTipText("请输入梯形的高度");
                break;

            case "10边星形":
                param1Label.setText("边长:");
                param2Label.setText("未使用:");
                parameter2Field.setEnabled(false);
                parameter1Field.setToolTipText("请输入10边星形的边长");
                break;
        }

        // 刷新界面
        revalidate();
        repaint();
    }

    // 绘图面板内部类
    private class DrawingPanel extends JPanel {
        public DrawingPanel() {
            setPreferredSize(new Dimension(500, 400));
            setBackground(Color.WHITE);
            setBorder(BorderFactory.createTitledBorder("图形预览"));
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);

            // 修复：使用局部变量避免条件始终为true的问题
            Shape shapeToDraw = currentShape;

            if (shapeToDraw != null) {
                drawCurrentShape(g, shapeToDraw);
            } else if (!shapes.isEmpty()) {
                drawAllShapes(g);
            } else {
                g.setColor(Color.GRAY);
                g.setFont(new Font("宋体", Font.PLAIN, 16));
                g.drawString("请输入参数并点击计算", getWidth()/2 - 80, getHeight()/2);
            }
        }

        private void drawCurrentShape(Graphics g, Shape shape) {
            Graphics2D g2d = (Graphics2D) g;
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

            int centerX = getWidth() / 2;
            int centerY = getHeight() / 2;
            int baseSize = Math.min(getWidth(), getHeight()) / 3;

            g2d.setColor(Color.BLUE);
            g2d.setStroke(new BasicStroke(2));

            String shapeType = shape.getName();
            if (shapeType.contains("长方")) {
                drawRectangle(g2d, centerX - baseSize, centerY - baseSize/2, baseSize * 2, baseSize);
            } else if (shapeType.contains("圆") && !shapeType.contains("环")) {
                drawCircle(g2d, centerX, centerY, baseSize);
            } else if (shapeType.contains("三角")) {
                drawTriangle(g2d, centerX, centerY, baseSize);
            } else if (shapeType.contains("正") && shapeType.contains("边")) {
                // 正多边形绘制
                try {
                    RegularPolygon poly = (RegularPolygon) shape;
                    drawRegularPolygon(g2d, centerX, centerY, baseSize, poly.getSideCount());
                } catch (Exception e) {
                    drawRegularPolygon(g2d, centerX, centerY, baseSize, 6);
                }
            } else if (shapeType.contains("椭圆")) {
                // 椭圆绘制
                drawEllipse(g2d, centerX, centerY, baseSize, baseSize * 2/3);
            } else if (shapeType.contains("菱形")) {
                drawRhombus(g2d, centerX, centerY, baseSize);
            } else if (shapeType.contains("圆环")) {
                drawAnnulus(g2d, centerX, centerY, baseSize * 2/3, baseSize);
            } else if (shapeType.contains("平行")) {
                drawParallelogram(g2d, centerX, centerY, baseSize);
            } else if (shapeType.contains("梯形")) {
                drawTrapezoid(g2d, centerX, centerY, baseSize);
            } else if (shapeType.contains("扇形")) {
                // 扇形绘制
                drawSector(g2d, centerX, centerY, baseSize);
            } else if (shapeType.contains("10边星形")) {
                // 10边星形绘制
                drawStar(g2d, centerX, centerY, baseSize, 10);
            } else {
                drawRectangle(g2d, centerX - baseSize/2, centerY - baseSize/2, baseSize, baseSize);
            }

            g2d.setColor(Color.RED);
            g2d.setFont(new Font("宋体", Font.BOLD, 14));
            g2d.drawString(shapeType, centerX - 20, centerY + baseSize + 20);
        }

        private void drawAllShapes(Graphics g) {
            Graphics2D g2d = (Graphics2D) g;
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

            int shapeSize = Math.min(getWidth(), getHeight()) / 4;
            int cols = 3;
            int index = 0;

            for (Shape shape : shapes) {
                int row = index / cols;
                int col = index % cols;
                int x = col * shapeSize + 30;
                int y = row * shapeSize + 30;

                Color shapeColor = new Color(
                        (100 + index * 40) % 255,
                        (150 + index * 30) % 255,
                        (200 + index * 20) % 255
                );

                g2d.setColor(shapeColor);
                g2d.setStroke(new BasicStroke(2));

                String shapeName = shape.getName();
                drawSmallShape(g2d, shapeName, shape, x, y, shapeSize);

                g2d.setColor(Color.BLACK);
                g2d.setFont(new Font("宋体", Font.PLAIN, 10));
                String displayName = shapeName.length() > 4 ? shapeName.substring(0, 4) : shapeName;
                g2d.drawString(displayName, x + 5, y + shapeSize - 5);

                index++;
                if (index >= 9) break;
            }
        }

        // 修复：提取重复的小图形绘制代码
        private void drawSmallShape(Graphics2D g2d, String shapeName, Shape shape, int x, int y, int shapeSize) {
            int centerX = x + shapeSize/2;
            int centerY = y + shapeSize/2;
            int radius = shapeSize/2 - 5;

            if (shapeName.contains("长方")) {
                g2d.drawRect(x, y, shapeSize - 20, shapeSize - 30);
            } else if (shapeName.contains("圆") && !shapeName.contains("环")) {
                g2d.drawOval(x, y, shapeSize - 20, shapeSize - 20);
            } else if (shapeName.contains("三角")) {
                int[] xPoints = {centerX, x, x + shapeSize - 20};
                int[] yPoints = {y, y + shapeSize - 20, y + shapeSize - 20};
                g2d.drawPolygon(xPoints, yPoints, 3);
            } else if (shapeName.contains("平行")) {
                int[] xPoints = {x, x + shapeSize - 20, x + shapeSize - 10, x - 10};
                int[] yPoints = {y, y, y + shapeSize - 20, y + shapeSize - 20};
                g2d.drawPolygon(xPoints, yPoints, 4);
            } else if (shapeName.contains("梯形")) {
                int[] xPoints = {x + 10, x + shapeSize - 30, x + shapeSize - 20, x};
                int[] yPoints = {y, y, y + shapeSize - 20, y + shapeSize - 20};
                g2d.drawPolygon(xPoints, yPoints, 4);
            } else if (shapeName.contains("菱形")) {
                int[] xPoints = {centerX, x + shapeSize - 20, centerX, x};
                int[] yPoints = {y, centerY, y + shapeSize - 20, centerY};
                g2d.drawPolygon(xPoints, yPoints, 4);
            } else if (shapeName.contains("椭圆")) {
                g2d.drawOval(x, y + 10, shapeSize - 20, shapeSize - 30);
            } else if (shapeName.contains("扇形")) {
                drawSector(g2d, centerX, centerY, radius);
            } else if (shapeName.contains("正") && shapeName.contains("边")) {
                try {
                    RegularPolygon poly = (RegularPolygon) shape;
                    drawRegularPolygon(g2d, centerX, centerY, radius, poly.getSideCount());
                } catch (Exception e) {
                    drawRegularPolygon(g2d, centerX, centerY, radius, 6);
                }
            } else if (shapeName.contains("10边星形")) {
                drawStar(g2d, centerX, centerY, radius, 10);
            } else {
                g2d.drawRect(x, y, shapeSize - 20, shapeSize - 20);
            }
        }

        // 基本图形绘制方法
        private void drawRectangle(Graphics2D g2d, int x, int y, int width, int height) {
            g2d.drawRect(x, y, width, height);
        }

        private void drawCircle(Graphics2D g2d, int centerX, int centerY, int radius) {
            g2d.drawOval(centerX - radius, centerY - radius, radius * 2, radius * 2);
        }

        private void drawTriangle(Graphics2D g2d, int centerX, int centerY, int baseSize) {
            int height = (int) (baseSize * 0.866);
            int[] xPoints = {centerX, centerX - baseSize/2, centerX + baseSize/2};
            int[] yPoints = {centerY - height/2, centerY + height/2, centerY + height/2};
            g2d.drawPolygon(xPoints, yPoints, 3);
        }

        private void drawEllipse(Graphics2D g2d, int centerX, int centerY, int width, int height) {
            g2d.drawOval(centerX - width/2, centerY - height/2, width, height);
        }

        private void drawRhombus(Graphics2D g2d, int centerX, int centerY, int size) {
            int[] xPoints = {centerX, centerX + size/2, centerX, centerX - size/2};
            int[] yPoints = {centerY - size/2, centerY, centerY + size/2, centerY};
            g2d.drawPolygon(xPoints, yPoints, 4);
        }

        private void drawAnnulus(Graphics2D g2d, int centerX, int centerY, int innerRadius, int outerRadius) {
            g2d.drawOval(centerX - outerRadius, centerY - outerRadius, outerRadius * 2, outerRadius * 2);
            g2d.drawOval(centerX - innerRadius, centerY - innerRadius, innerRadius * 2, innerRadius * 2);
        }

        private void drawParallelogram(Graphics2D g2d, int centerX, int centerY, int size) {
            int[] xPoints = {centerX - size, centerX, centerX + size, centerX};
            int[] yPoints = {centerY - size/3, centerY - size/3, centerY + size/3, centerY + size/3};
            g2d.drawPolygon(xPoints, yPoints, 4);
        }

        private void drawTrapezoid(Graphics2D g2d, int centerX, int centerY, int size) {
            int[] xPoints = {centerX - size, centerX - size/2, centerX + size/2, centerX + size};
            int[] yPoints = {centerY + size/3, centerY - size/3, centerY - size/3, centerY + size/3};
            g2d.drawPolygon(xPoints, yPoints, 4);
        }

        // 正多边形绘制
        private void drawRegularPolygon(Graphics2D g2d, int centerX, int centerY, int radius, int sides) {
            Polygon polygon = new Polygon();
            for (int i = 0; i < sides; i++) {
                double angle = 2 * Math.PI * i / sides - Math.PI / 2;
                int px = centerX + (int) (radius * Math.cos(angle));
                int py = centerY + (int) (radius * Math.sin(angle));
                polygon.addPoint(px, py);
            }
            g2d.drawPolygon(polygon);
        }

        // 扇形绘制
        private void drawSector(Graphics2D g2d, int centerX, int centerY, int radius) {
            // 绘制一个90度的扇形
            g2d.drawArc(centerX - radius, centerY - radius, radius * 2, radius * 2, 0, 90);
            g2d.drawLine(centerX, centerY, centerX + radius, centerY);
            g2d.drawLine(centerX, centerY, centerX, centerY - radius);
        }

        // 修复：统一的星形绘制方法，避免重复代码
        private void drawStar(Graphics2D g2d, int centerX, int centerY, int radius, int points) {
            int innerRadius = radius * 2 / 3;

            Polygon star = new Polygon();
            for (int i = 0; i < points * 2; i++) {
                double angle = Math.PI * i / points - Math.PI / 2;
                int currentRadius = (i % 2 == 0) ? radius : innerRadius;
                int x = centerX + (int) (currentRadius * Math.cos(angle));
                int y = centerY + (int) (currentRadius * Math.sin(angle));
                star.addPoint(x, y);
            }
            g2d.drawPolygon(star);
        }
    }

    // 计算监听器内部类
    private class CalculateListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            try {
                String shapeType = (String) shapeComboBox.getSelectedItem();
                if (shapeType == null) {
                    JOptionPane.showMessageDialog(PolygonGUI.this,
                            "请选择图形类型！", "错误", JOptionPane.ERROR_MESSAGE);
                    return;
                }

                double param1 = Double.parseDouble(parameter1Field.getText().trim());
                double param2 = 0;
                double param3 = 0;

                if (parameter2Field.isEnabled() && !parameter2Field.getText().trim().isEmpty()) {
                    param2 = Double.parseDouble(parameter2Field.getText().trim());
                }

                if (shapeType.equals("梯形") && !parameter3Field.getText().trim().isEmpty()) {
                    param3 = Double.parseDouble(parameter3Field.getText().trim());
                }

                currentShape = createShape(shapeType, param1, param2, param3);
                if (currentShape != null) {
                    shapes.add(currentShape);
                    updateInfoDisplay();
                    drawingPanel.repaint();

                    JOptionPane.showMessageDialog(PolygonGUI.this,
                            "📌 图形添加成功！\n" + currentShape.getInfo(),
                            "成功", JOptionPane.INFORMATION_MESSAGE);
                }

            } catch (NumberFormatException ex) {
                JOptionPane.showMessageDialog(PolygonGUI.this,
                        "请输入有效的数字！", "输入错误", JOptionPane.ERROR_MESSAGE);
            } catch (IllegalArgumentException ex) {
                JOptionPane.showMessageDialog(PolygonGUI.this,
                        ex.getMessage(), "参数错误", JOptionPane.ERROR_MESSAGE);
            } catch (Exception ex) {
                JOptionPane.showMessageDialog(PolygonGUI.this,
                        "创建图形时发生错误: " + ex.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
            }
        }

        private Shape createShape(String type, double param1, double param2, double param3) {
            try {
                switch (type) {
                    case "长方形":
                        return new Rectangle(param1, param2);
                    case "圆形":
                        return new Circle(param1);
                    case "三角形":
                        return new Triangle(param1, param2, Math.sqrt(param1*param1 + param2*param2));
                    case "正多边形":
                        return new RegularPolygon(param1, (int)param2);
                    case "菱形":
                        return new Rhombus(param1);
                    case "平行四边形":
                        return new Parallelogram(param1, param2);
                    case "梯形":
                        return new Trapezoid(param1, param2, param3);
                    case "椭圆":
                        return new Ellipse(param1, param2);
                    case "扇形":
                        return new Sector(param1, param2);
                    case "圆环":
                        return new Annulus(param1, param2);
                    case "10边星形":
                        return new DecagonStar(param1);
                    default:
                        throw new IllegalArgumentException("不支持的图形类型: " + type);
                }
            } catch (Exception e) {
                throw new IllegalArgumentException("创建" + type + "失败: " + e.getMessage());
            }
        }
    }

    private void updateInfoDisplay() {
        // 修复：避免条件始终为true的问题
        if (currentShape == null) {
            infoTextArea.setText("暂无当前图形信息");
            return;
        }

        StringBuilder sb = new StringBuilder();
        sb.append("==== 当前图形信息 ====\n");
        sb.append(currentShape.getInfo()).append("\n\n");

        sb.append("==== 所有已添加图形 ====\n");
        if (shapes.isEmpty()) {
            sb.append("暂无图形\n");
        } else {
            for (int i = 0; i < shapes.size(); i++) {
                sb.append(i + 1).append(" | ").append(shapes.get(i).getInfo()).append("\n");
            }
        }

        infoTextArea.setText(sb.toString());
    }

    private void showAllShapes() {
        if (shapes.isEmpty()) {
            JOptionPane.showMessageDialog(this, "暂无图形数据", "信息", JOptionPane.INFORMATION_MESSAGE);
            return;
        }

        StringBuilder sb = new StringBuilder("==== 所有已添加图形 ====\n");
        sb.append("序号 | 图形详情\n");
        sb.append("--- | ---\n");
        for (int i = 0; i < shapes.size(); i++) {
            sb.append(i + 1).append(" | ").append(shapes.get(i).getInfo()).append("\n");
        }

        infoTextArea.setText(sb.toString());
        currentShape = null;
        drawingPanel.repaint();
    }

    private void showStatistics() {
        if (shapes.isEmpty()) {
            JOptionPane.showMessageDialog(this, "暂无图形数据", "信息", JOptionPane.INFORMATION_MESSAGE);
            return;
        }

        double totalArea = 0;
        double totalPerimeter = 0;

        for (Shape shape : shapes) {
            totalArea += shape.calculateArea();
            totalPerimeter += shape.calculatePerimeter();
        }

        String stats = String.format(
                "==== 统计信息 ====\n" +
                        "图形总数: %d\n" +
                        "总面积: %.2f\n" +
                        "总周长: %.2f\n" +
                        "平均面积: %.2f\n" +
                        "平均周长: %.2f",
                shapes.size(), totalArea, totalPerimeter,
                totalArea / shapes.size(), totalPerimeter / shapes.size()
        );

        infoTextArea.setText(stats);
    }

    private void clearShapes() {
        int result = JOptionPane.showConfirmDialog(this,
                "确定要清空所有图形吗？", "确认清空", JOptionPane.YES_NO_OPTION);

        if (result == JOptionPane.YES_OPTION) {
            shapes.clear();
            currentShape = null;
            infoTextArea.setText("图形数据已清空");
            drawingPanel.repaint();

            parameter1Field.setText("");
            parameter2Field.setText("");
            parameter3Field.setText("");
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new PolygonGUI().setVisible(true));
    }
}